
package p2pgame;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Random;

import p2pgame.LudoApp;

import rice.environment.Environment;
import rice.p2p.commonapi.Id;
import rice.pastry.commonapi.PastryIdFactory;

// represents our UI. Quite simple at the moment.
public class LudoController extends BasicSocket {

	LudoApp app;
	Player p = null;
	
	public LudoController(int bindport, InetSocketAddress bootaddress, Environment env) throws Exception {
		super(bindport,bootaddress,env);
		app = new LudoApp(node,env);

		// code needed for keyboard input
		BufferedReader br = new BufferedReader(
				new InputStreamReader(System.in));
		String temp;

		// Peer not yet in a game


		
		while(p==null){
			
			System.out.print("Enter command ('help' for help)> ");

			temp = br.readLine();

			if (temp.equals("help")) help();
			if (temp.equals("status")) status();
			if (temp.equals("start")) start();
			if (temp.equals("log")) log();
			if (temp.startsWith("join ")) {
				String idString = temp.substring(5);
				Id id = new PastryIdFactory(env).buildIdFromToString(idString);
				app.joinGame(id);
				System.out.println("Waiting for game start from node "+ id.toStringFull() + " ...");
				while(app.players.size()==0){
					env.getTimeSource().sleep(500);					
				}
			}
			if ( app.players.size()>0 ) {
				p=app.players.get(0);
				p.updateView();
			}

		}
		
		System.out.println("The game of Ludo has now started.");
		// TODO: Show this players player-number
		
		
		// Player has now joined another peer for a game of Ludo
		boolean displayWait = true; 
		int playerNo = p.game.players.indexOf(app.getPeerId());
		while(true){
			if (p.game.getPlayerInTurn().equals(app.getPeerId())){
				System.out.print("Player " + playerNo + ", enter square to move from, -1 to pass> ");
				temp = br.readLine();
	
				int i = -2;
				try{
					// Send move message to player
					i = Integer.parseInt(temp);
					if ( p.move(i) ) {
						System.out.println("Sending move ...");
						displayWait = true;
					} else {
						System.out.println("Illegal move!");
					}
				} catch (Exception e){
				}
			} else if ( displayWait ){
				
				System.out.println("Please wait while other players make their moves ...");
				displayWait = false;
			}
			
			env.getTimeSource().sleep(1000);
		}

	}
	
	public void log(){
		if ( Util.logging ){
			System.out.println("Logging is now OFF");
			Util.logging = false;
		} else {
			System.out.println("Logging is now ON");
			Util.logging = true;
		}
	}
	
	public void help(){
		System.out.println("---- Commands ----");
		System.out.println("help - help");
		System.out.println("join [node ID] - join peer [node ID] for a nice game of ludo");
		System.out.println("status - display connection status");
		System.out.println("start - start game with connected peers (only if you're the initiator");
		System.out.println("log - toggle logging of message communication");
	}

	public void status(){
		System.out.println("Your ID is "+app.getPeerId().toStringFull());
		if ( app.initiator==null){
			System.out.println("You haven't yet joined any peer for a game of Ludo");
		} else if ( app.initiator.equals(app.getPeerId())){
			System.out.println("You are game initiator");
			System.out.println("Players waiting to play:");
			for(Id id: app.nextGame){
				System.out.println("* "+id.toStringFull());
			}
		} else {
			System.out.println("You are waiting for Peer "+ app.initiator.toStringFull() + " to start the game.");
		}
	
		System.out.println("You are op in the following games:");
		for(Op op: app.ops){
			System.out.println("* "+op.game.gameId.toStringFull());
		}
	
	}
	
	

	public void start(){
		// Start game!
		System.out.println("Starting game ...");
		if ( app.startGame()){
			app.startGame();
		} else {
			System.out.println("Couldn't start game - maybe you're not initiator ...");
		}
	}
	
	/**
	 * Usage: 
	 * java [-cp FreePastry-<version>.jar] rice.tutorial.lesson3.DistTutorial localbindport bootIP bootPort
	 * example java rice.tutorial.DistTutorial 9001 pokey.cs.almamater.edu 9001
	 */
	public static void main(String[] args) throws Exception {
		// Loads pastry settings
		Environment env = new Environment();

		// disable the UPnP setting (in case you are testing this on a NATted LAN)
		env.getParameters().setString("nat_search_policy","never");
		
		// set binding to localhost
		env.getParameters().setString("socket_bindAddress","127.0.0.1");
		
		try {
			// the port to use locally
			int bindport = Integer.parseInt(args[0]);
			
			// Select random bindport
			// Pastry will auto-select another port if it's already in use
			if ( bindport == -1){
				bindport = new Random().nextInt(50000)+1100;
				//Integer.parseInt(args[0]);
			}
			
			// Enable logging from command line?
			int logging = Integer.parseInt(args[3]);
			if (logging==1) Util.logging=true; else Util.logging=false;
			
			// build the bootaddress from the command line args
			InetAddress bootaddr = InetAddress.getByName(args[1]);
			int bootport = Integer.parseInt(args[2]);
			InetSocketAddress bootaddress = new InetSocketAddress(bootaddr,bootport);

			// launch our node!
			new LudoController(bindport, bootaddress, env);
		} catch (Exception e) {
			// remind user how to use
			System.out.println("Usage:"); 
			System.out.println("java [-cp FreePastry-<version>.jar] rice.tutorial.lesson3.DistTutorial localbindport bootIP bootPort");
			System.out.println("example java rice.tutorial.DistTutorial 9001 pokey.cs.almamater.edu 9001");
			throw e; 
		}
	}
}
